/*
	常见增删改查操作的公用及辅助函数
 */
var rs = (function(rs) {
	'use strict';


	/*----------------------------------------------树形结构的主流程-------------------------*/
	/**
	 * 适用于树形结构列表的查询
	 * @param	urlQuery  后台服务
	 * @param	treeGridMaster 树形列表treegrid 对象
	 * @param  	id   树形列表id
	 * @param  	fid  树形列表父id
	 * @param	searchFormId   查询窗口id  
	 * @param	showTips   是否显示提示信息，缺省值为true
	 * 
	 */
	rs.onTreeQueryMaster = function(urlQuery, treeGridMaster, id, fid, searchFormId, showTips) {
		try {
			urlQuery = urlQuery || window.urlQuery;
			treeGridMaster = treeGridMaster || rs.get('treeGridMaster');
			searchFormId = searchFormId || 'searchInfo';
			showTips = (showTips !== undefined) ? showTips : true;

			var param = {};
			var arr = $('form#' + searchFormId);
			if (arr.length === 1) {
				param = rs.newForm(searchFormId).getData();
			}
			param.opttype = Constants.OPT_QUERY;
			param.mkid = mkid;

			jQuery.post(urlQuery, param, function(ret) {
				ret = ret.result || ret;
				if (ret.ret_code.startsWith('0000')) {
					if (ret.data && ret.data.length === 0) {
						showTips && rs.showTipsSuccess('查询成功，无数据');
					} else {
						showTips && rs.showTipsSuccess('查询成功');
					}
					treeGridMaster.loadList(ret.data, id, fid);
				} else {
					showTips && rs.showMessageBoxError('查询失败，' + (ret.ret_desc || '请检查重试'));
				}
			});
		} catch (e) {
			printException('onTreeQueryMaster', e);
		}
	};
	/**
	 * 适用于树形结构列表的删除
	 * @param urlModify  删除操作url
	 * @param urlQuery   查询操作url
	 * @param treeGridMaster  树形列表对象
	 * @param id         树列表id
	 * @param fid        树列表父id
	 * 
	 */
	rs.onTreeRemoveMaster = function(urlModify, urlQuery, treeGridMaster, id, fid) {
		try {
			treeGridMaster = treeGridMaster || rs.get('treeGridMaster');
			urlModify = urlModify || window.urlModify;
			urlQuery = urlQuery || window.urlQuery;
			var record = treeGridMaster.getSelected();
			if (!record) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}
			rs.confirm('您确认删除选中的数据吗?', '提示', function(action) {
				if (action === 'ok') {
					opttype = Constants.OPT_DEL;
					var item = jQuery.extend(true, {}, record);
					prehandleMiniItem(treeGridMaster.type, item);

					var param = jQuery.extend(true, {}, item);
					param.oldData = item;
					param.opttype = opttype;
					param.mkid = mkid;

					rs.postJson({
						url: urlModify,
						data: param,
						success: function(ret) {
							if (ret.ret_code.startsWith('0000')) {
								rs.showTipsSuccess('删除成功');
								rs.onTreeQueryMaster(urlQuery, treeGridMaster, id, fid, null, false);
							} else {
								rs.showMessageBoxError('删除失败，' + (ret.ret_desc || '请检查重试'));
							}
						},
						error: function() {
							rs.showMessageBoxError('删除失败，请检查重试');
						}
					});
				}
			});
		} catch (e) {
			printException('onTreeRemoveMaster', e);
		}
	};


	/**
	 * 适用于树形列表的通用保存函数
	 * 
	 * @param  flag - true: 保存并新增，其他：保存
	 * @param  windowPopup - 弹出窗口对象
	 * @param  formPopup - 弹出窗口的表单对象
	 * @param  treeGridMaster - 主表表格对象
	 * @param  id           树形列表的id
	 * @param  fid		树形列表的父id
	 * @param  urlModify    新增和修改的url
	 * @param  urlQuery     查询的url
	 */
	rs.onTreeSaveMaster = function(flag, windowPopup, formPopup, treeGridMaster, id, fid, urlModify, urlQuery) {
		var deferred = jQuery.Deferred();
		try {
			flag = (flag !== undefined) ? flag : false;
			windowPopup = windowPopup || rs.get('windowPopup');
			formPopup = formPopup || rs.newForm('formPopup');
			treeGridMaster = treeGridMaster || rs.get('treeGridMaster');
			urlModify = urlModify || window.urlModify;
			urlQuery = urlQuery || window.urlQuery;

			if (!rs.formValidation(formPopup)) {
				deferred.reject();
				return deferred.promise();
			}

			var param = jQuery.extend(true, {}, formPopup.getData());
			if (opttype === Constants.OPT_INSERT) {
				param.newData = formPopup.getData();
			} else if (opttype === Constants.OPT_EDIT) {
				// 编辑操作返回修改数据及原数据
				var newData = formPopup.getData();
				param.oldData = minus(window.gOldData, newData);
				param.newData = newData;
				param.modifyData = compareData(window.gOldData, newData);
			}
			param.mkid = mkid;
			param.opttype = opttype;
			rs.postJson({
				url: urlModify,
				data: param,
				success: function(ret) {
					if (ret.ret_code.startsWith('0000')) {
						window.gOldData = null;
						rs.showTipsSuccess('保存成功');
						rs.onTreeQueryMaster(urlQuery, treeGridMaster, id, fid, null, false);
						if (!flag) {
							windowPopup.hide();
						} else {
							formPopup.reset();
						}
						deferred.resolve();
					} else {
						rs.showMessageBoxError('保存失败，' + (ret.ret_desc || '请检查重试'));
						deferred.reject();
					}
				},
				error: function() {
					rs.showMessageBoxError('保存失败，请检查重试');
					deferred.reject();
				}
			});
		} catch (e) {
			printException('onTreeSaveMaster', e);
			deferred.reject();
		}
		return deferred.promise();
	};



	/*------------------------------------------多选选择框-------------------------------------------*/
	/**
	 * 适用于下拉列表框的函数
	 * @param url  后台服务接口
	 * @param combox 下拉列表框对象
	 */
	rs.onComboxQueryMaster = function(url, combox, mkid, valueField, textField, isJZTY) {
		try {
			url = url || window.url;
			combox = combox || rs.get("combox");
			valueField = valueField;
			textField = textField;
			var param = {};
			param.opttype = Constants.OPT_QUERY;
			param.mkid = mkid;
			param.pageIndex = 0;
			param.pageSize = 100;
			$.post(url, param, function(ret) {
				if (ret.ret_code.startsWith('0000')) {
					var comboxData = [],
						data = [];
					data = ret.data;
					for (var i = 0; i < data.length; i++) {
						//未停用
						if (data[i].tybz == "N") {
							var temp = {
								"id": data[i][valueField],
								"text": data[i][textField]
							};
							comboxData.push(temp);
						}
					}
					if (isJZTY == "Y") {
						for (var i = 0; i < data.length; i++) {
							//未停用
							if (data[i].tybz == "Y") {
								var temp = {
									"id": data[i][valueField],
									"text": data[i][textField] + "(停用)"
								};
								comboxData.push(temp);
							}
						}
					}
					combox.setData(comboxData);
				} else {
					rs.alert(ret.ret_desc);
				}
			});
		} catch (e) {
			printException('onComboxQueryMaster', e);
		}

	};

	// 停用状态
	rs.onTybzRenderer = function(e) {
		var genders = [{
			id: 'Y',
			text: '停用'
		}, {
			id: 'N',
			text: '正常'
		}];
		for (var i = 0; i < genders.length; i++) {
			var g = genders[i];
			if (g.id == e.value) return g.text;
		}
		return "";
	};
	
	//发布状态
	rs.onFbRenderer = function(e) {
		var genders = [{
			id: 'I',
			text: '未发布'
		}, {
			id: 'C',
			text: '发布'
		}];
		for (var i = 0; i < genders.length; i++) {
			var g = genders[i];
			if (g.id == e.value) return g.text;
		}
		return "";
	};
	
	rs.onFbbzRenderer = function(e) {
		var genders = [{
			id: 'N',
			text: '未发布'
		}, {
			id: 'Y',
			text: '发布'
		}];
		for (var i = 0; i < genders.length; i++) {
			var g = genders[i];
			if (g.id == e.value) return g.text;
		}
		return "";
	};
	
	//失效状态
	rs.onSXRenderer = function(e) {
		var genders = [{
			id: 'Y',
			text: '失效'
		}, {
			id: 'N',
			text: '有效'
		}];
		for (var i = 0; i < genders.length; i++) {
			var g = genders[i];
			if (g.id == e.value) return g.text;
		}
		return "";
	};
	
	//确认状态
	rs.onQRRenderer = function(e) {
		var genders = [{
			id: 'Y',
			text: '已确认'
		}, {
			id: 'N',
			text: '未确认'
		}];
		for (var i = 0; i < genders.length; i++) {
			var g = genders[i];
			if (g.id == e.value) return g.text;
		}
		return "";
	};

	//下拉框
	rs.onComboxRenderer = function(e) {
		var genders = [{
			'id': 'a',
			'text': '个'
		}, {
			'id': 'b',
			'text': '件'
		}];
		for (var i = 0; i < genders.length; i++) {
			var g = genders[i];
			if (g.id == e.value) return g.text;
		}
		return "";
	}

	/***********************************************************************************************************************************************************/



	/*------------------------------------- 主体流程类开始 ----------------------------------*/
	/**
	 * 适用于单表模式的通用查询函数
	 * 
	 * @param  urlQuery - 后台服务接口
	 * @param  gridMaster - 主表grid对象
	 * @param  searchFormId - 查询窗口ID
	 * @param  showTips - 是否显示提示信息，缺省值为true
	 */
	rs.onQueryMaster = function(urlQuery, gridMaster, searchFormId, showTips, reload) {
		var deferred = jQuery.Deferred();
		try {
			urlQuery = urlQuery || window.urlQuery;
			gridMaster = gridMaster || rs.get('gridMaster');
			searchFormId = searchFormId || 'searchInfo';
			showTips = (showTips !== undefined) ? showTips : true;
			reload = (reload !== undefined) ? reload : false;

			var param = {};
			var arr = jQuery('form#' + searchFormId);
			if (arr.length === 1) {
				var searchForm = rs.newForm(searchFormId);
				if (!rs.formValidation(searchForm)) {
					deferred.reject();
					return deferred.promise();
				}
			
				param = searchForm.getData();
			}
			param.opttype = Constants.OPT_QUERY;
			param.mkid = mkid;

			gridMaster.setUrl(urlQuery);
			if (!reload) {
				gridMaster.load(param, function(ret) {
					if (showTips) {
						ret = ret.result;
						if (ret.ret_code.startsWith('0000')) {
							if (ret.data && ret.data.length === 0) {
								rs.showTipsSuccess('查询成功，无数据');
							} else {
								rs.showTipsSuccess('查询成功');
							}
							deferred.resolve();
						} else {
							rs.showMessageBoxError('查询失败，' + (ret.ret_desc || '请检查重试'));
							deferred.reject();
						}
					}else{
						deferred.resolve();
					}
				}, function() {
					rs.showMessageBoxError('查询失败，请检查重试');
					deferred.reject();
				});
			} else {
				gridMaster.reload();
			}
		} catch (e) {
			printException('onQueryMaster', e);
			deferred.reject();
		}
		return deferred.promise();
	};

	/**
	 * 适用于单表模式的通用新增函数
	 * 
	 * @param  title - 弹出窗口标题
	 * @param  windowWidth - 弹出窗口宽度
	 * @param  windowHeight - 弹出窗口高度
	 * @param  windowPopup - 弹出窗口对象
	 * @param  formPopup - 弹出窗口的表单对象
	 * @param  editModeDisabledIds - 编辑模式下禁用的控件ID列表
	 */
	rs.onAddMaster = function(title, windowWidth, windowHeight, windowPopup, formPopup, editModeDisabledIds) {
		try {
			title = title || '新增记录';
			windowWidth = windowWidth || 650;
			windowHeight = windowHeight || 400;
			windowPopup = windowPopup || rs.get('windowPopup');
			formPopup = formPopup || rs.newForm('formPopup');
			editModeDisabledIds = editModeDisabledIds || [];

			opttype = Constants.OPT_INSERT;

			editModeDisabledIds.forEach(function(id) {
				rs.setEnable(id);
			});
			rs.show('btnsaveadd');
			rs.showWindow(windowPopup, windowWidth, windowHeight, title, formPopup, {
				allowResize: false
			});
		} catch (e) {
			printException('onAddMaster', e);
		}
	};

	/**
	 * 适用于单表模式的通用修改函数
	 * 
	 * @param  title - 弹出窗口标题
	 * @param  windowWidth - 弹出窗口宽度
	 * @param  windowHeight - 弹出窗口高度
	 * @param  windowPopup - 弹出窗口对象
	 * @param  formPopup - 弹出窗口的表单对象
	 * @param  gridMaster - 主表表格对象
	 * @param  editModeDisabledIds - 编辑模式下禁用的控件ID列表
	 */
	rs.onEditMaster = function(title, windowWidth, windowHeight, windowPopup, formPopup, gridMaster, editModeDisabledIds) {
		try {
			title = title || '修改记录';
			windowWidth = windowWidth || 650;
			windowHeight = windowHeight || 400;
			windowPopup = windowPopup || rs.get('windowPopup');
			formPopup = formPopup || rs.newForm('formPopup');
			gridMaster = gridMaster || rs.get('gridMaster');
			editModeDisabledIds = editModeDisabledIds || [];

			var record = gridMaster.getSelected();
			if (!record) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}

			var item = jQuery.extend(true, {}, record);
			prehandleMiniItem(gridMaster.type, item);

			window.opttype = Constants.OPT_EDIT;
			window.gOldData = item;

			editModeDisabledIds.forEach(function(id) {
				rs.setDisable(id);
			});
			rs.hide('btnsaveadd');
			showWindow(windowPopup, windowWidth, windowHeight, title, formPopup, {
				allowResize: false
			});
			formPopup.setData(item);
		} catch (e) {
			printException('onEditMaster', e);
		}
	};

	/**
	 * 适用于单表模式的通用删除函数
	 * 
	 * @param  gridMaster - 主表表格对象
	 * @param  urlModify - 后台服务修改地址
	 * @param  urlQuery - 后台服务查询接口
	 * @param  bRefresh - true：保存完刷新最新数据，false：保存完不刷新最新数据
	 */
	rs.onRemoveMaster = function(gridMaster, urlModify, urlQuery, bRefresh) {
		try {
			gridMaster = gridMaster || rs.get('gridMaster');
			urlModify = urlModify || window.urlModify;
			urlQuery = urlQuery || window.urlQuery;
			bRefresh = (bRefresh !== undefined) ? bRefresh : true;

			var record = gridMaster.getSelected();
			if (!record) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}
			rs.confirm('您确认删除选中的数据吗?', '提示', function(action) {
				if (action === 'ok') {
					opttype = Constants.OPT_DEL;

					var item = jQuery.extend(true, {}, record);
					prehandleMiniItem(gridMaster.type, item);

					var param = jQuery.extend(true, {}, item);
					param.oldData = item;
					param.opttype = opttype;
					param.mkid = mkid;
					rs.postJson({
						url: urlModify,
						data: param,
						success: function(ret) {
							if (ret.ret_code.startsWith('0000')) {
								rs.showTipsSuccess('删除成功');
								if (bRefresh) {
									rs.onQueryMaster(urlQuery, gridMaster, null, false, true);
								}
							} else {
								rs.showMessageBoxError('删除失败，' + (ret.ret_desc || '请检查重试'));
							}
						},
						error: function() {
							rs.showMessageBoxError('删除失败，请检查重试');
						}
					});
				}
			});
		} catch (e) {
			printException('onRemoveMaster', e);
		}
	};

	/**
	 * 适用于单表模式的通用复制函数
	 * 
	 * @param  title - 弹出窗口标题
	 * @param  windowWidth - 弹出窗口宽度
	 * @param  windowHeight - 弹出窗口高度
	 * @param  windowPopup - 弹出窗口对象
	 * @param  formPopup - 弹出窗口的表单对象
	 * @param  gridMaster - 主表表格对象
	 * @param  editModeDisabledIds - 编辑模式下禁用的控件ID列表
	 */
	rs.onCopyMaster = function(title, windowWidth, windowHeight, windowPopup, formPopup, gridMaster, editModeDisabledIds) {
		try {
			title = title || '新增记录窗口名称';
			windowWidth = windowWidth || 650;
			windowHeight = windowHeight || 400;
			windowPopup = windowPopup || rs.get('windowPopup');
			formPopup = formPopup || rs.newForm('formPopup');
			gridMaster = gridMaster || rs.get('gridMaster');
			editModeDisabledIds = editModeDisabledIds || [];

			var item = gridMaster.getSelected();
			if (!item) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}

			opttype = Constants.OPT_INSERT;

			editModeDisabledIds.forEach(function(id) {
				rs.setEnable(id);
			});
			rs.hide('btnsaveadd');
			showWindow(windowPopup, windowWidth, windowHeight, title, formPopup, {
				allowResize: false
			});
			formPopup.setData(item);
		} catch (e) {
			printException('onCopyMaster', e);
		}
	};

	/**
	 * 适用于单表模式的通用保存函数
	 * 
	 * @param  flag - true: 保存并新增，其他：保存
	 * @param  windowPopup - 弹出窗口对象
	 * @param  formPopup - 弹出窗口的表单对象
	 * @param  gridMaster - 主表表格对象
	 * @param  urlModify - 后台服务修改地址
	 * @param  urlQuery - 后台服务查询接口
	 * @param  bRefresh - true：保存完刷新最新数据，false：保存完不刷新最新数据
	 */
	rs.onSaveMaster = function(flag, windowPopup, formPopup, gridMaster, urlModify, urlQuery, bRefresh) {
		var deferred = jQuery.Deferred();
		// 支持函数签名：rs.onSaveMaster(settings)
		var postSuccess, postError, error;
		if (typeof flag === 'object') {
			var settings = flag;
			flag = settings.flag;
			windowPopup = settings.windowPopup;
			formPopup = settings.formPopup;
			gridMaster = settings.gridMaster;
			urlModify = settings.urlModify;
			urlQuery = settings.urlQuery;
			bRefresh = settings.bRefresh;
			postSuccess = settings.postSuccess;
			postError = settings.postError;
			error = settings.error;
		}

		try {
			flag = (flag !== undefined) ? flag : false;
			windowPopup = windowPopup || rs.get('windowPopup');
			formPopup = formPopup || rs.newForm('formPopup');
			gridMaster = gridMaster || rs.get('gridMaster');
			urlModify = urlModify || window.urlModify;
			urlQuery = urlQuery || window.urlQuery;
			bRefresh = (bRefresh !== undefined) ? bRefresh : true;

			if (!rs.formValidation(formPopup)) {
				deferred.reject();
				return deferred.promise();
			}

			var param = jQuery.extend(true, {}, formPopup.getData());
			if (opttype === Constants.OPT_INSERT) {
				param.newData = formPopup.getData();
			} else if (opttype === Constants.OPT_EDIT) {
				// 编辑操作返回修改数据及原数据
				var newData = formPopup.getData();
				param.oldData = minus(window.gOldData, newData);
				param.newData = newData;
				param.modifyData = compareData(window.gOldData, newData);

				if (!isDataModified(param)) {
					rs.showTipsSuccess('数据未修改');
					if (windowPopup) {
						windowPopup.hide();
					}
					deferred.resolve();
					return deferred.promise();
				}
			}

			param.mkid = mkid;
			param.opttype = opttype;
			rs.postJson({
				url: urlModify,
				data: param,
				success: function(ret, textStatus, jqXHR) {
					if (ret.ret_code.startsWith('0000')) {
						window.gOldData = null;
						if (ret.ret_code === '0000') {
							rs.showTipsSuccess('保存成功');
						} else {
							rs.showTipsSuccess(ret.ret_desc);
						}
						if (bRefresh) {
							rs.onQueryMaster(urlQuery, gridMaster, null, false, true);
						}
						if (flag) {
							formPopup.reset();
						} else {
							if (windowPopup) {
								windowPopup.hide();
							}
						}
						deferred.resolve();
					} else {
						if (typeof error === 'function') {
							error(ret, textStatus, jqXHR);
						} else {
							rs.showMessageBoxError('保存失败，' + (ret.ret_desc || '请检查重试'));
						}
						deferred.reject();
					}

					if (typeof postSuccess === 'function') {
						postSuccess(ret, textStatus, jqXHR);
					}
				},
				error: function(jqXHR, textStatus, errorThrown) {
					rs.showMessageBoxError('保存失败，请检查重试');

					if (typeof postError === 'function') {
						postError(jqXHR, textStatus, errorThrown);
					}
					deferred.reject();
				}
			});
		} catch (e) {
			printException('onSaveMaster', e);
			deferred.reject();
		}
		return deferred.promise();
	};

	/*------------------------------------- 主体流程类开始 ----------------------------------*/
	/**
	 * 适用于主从表模式的通用查询函数
	 * 
	 * @param  urlQuery - 后台服务接口
	 * @param  gridMaster - 主表grid对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  splitter - splitter控件
	 * @param  searchFormId - 【可选】查询窗口ID
	 * @param  showTips - 【可选】是否显示提示信息，缺省值为true
	 * @param  restoreLayout - 【可选】是否恢复为查询布局，缺省值为true
	 */
	rs.queryMasterDetail = function(urlQuery, gridMaster, formDetail, gridDetail, splitter, searchFormId, showTips, restoreLayout) {
		var deferred = jQuery.Deferred();
		try {
			urlQuery = urlQuery || window.urlQuery;
			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			splitter = splitter || window.splitter || rs.get('splitter');
			searchFormId = searchFormId || 'searchInfo';
			showTips = (showTips !== undefined) ? showTips : true;
			restoreLayout = (restoreLayout !== undefined) ? restoreLayout : true;

			// validation
			if (!isDatagrid(gridMaster) || !isDatagrid(gridDetail) || !isSplitter(splitter)) {
				printErrorIllegal('queryMasterDetail');
				deferred.reject();
				return deferred.promise();
			}

			var param = {};
			var arr = jQuery('form#' + searchFormId);
			if (arr.length === 1) {
				param = rs.newForm(searchFormId).getData();
			}
			param.opttype = Constants.OPT_QUERY;
			param.mkid = mkid;
			//param.pageSize = 0; // 主表数据不分页

			gridMaster.setUrl(urlQuery);
			gridMaster.load(param, function(ret) {
				if (restoreLayout) {
					rs.toggleSplitterPane(splitter, 1, true);
					rs.toggleSplitterPane(splitter, 2, false);
				}

				if (showTips) {
					ret = ret.result;
					if (ret.ret_code.startsWith('0000')) {
						if (ret.data && ret.data.length === 0) {
							rs.showTipsSuccess('查询成功，无数据');
						} else {
							rs.showTipsSuccess('查询成功');
						}
						deferred.resolve();
					} else {
						rs.showMessageBoxError('查询失败，' + (ret.ret_desc || '请检查重试'));
						deferred.reject();
					}
				}else{
					deferred.resolve();
				}
			}, function() {
				rs.showMessageBoxError('查询失败，请检查重试');
				deferred.reject();
			});
			changeViewMode(Constants.VIEWMODE_QUERY, formDetail, gridDetail, gridMaster);
		} catch (e) {
			deferred.reject();
			printException('queryMasterDetail', e);
		}
		return deferred.promise();
	};

	/**
	 * 适用于主从表模式的通用新增函数
	 * 
	 * @param  gridMaster - 主表grid对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  splitter - splitter控件
	 * @param  editModeDisabledIds - 【可选】编辑模式下禁用的控件ID列表
	 */
	rs.addMasterDetail = function(gridMaster, formDetail, gridDetail, splitter, editModeDisabledIds) {
		try {
			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			splitter = splitter || window.splitter || rs.get('splitter');
			editModeDisabledIds = editModeDisabledIds || window.editModeDisabledIds || [];

			rs.toggleSplitterPane(splitter, 1, false);
			rs.toggleSplitterPane(splitter, 2, true);

			opttype = Constants.OPT_INSERT;

			// 处理控件
			changeViewMode(Constants.VIEWMODE_INSERT, formDetail, gridDetail, gridMaster);
			editModeDisabledIds.forEach(function(id) {
				rs.setEnable(id);
			});
		} catch (e) {
			printException('addMasterDetail', e);
		}
	};

	/**
	 * 适用于主从表模式的通用编辑函数
	 * 
	 * @param  gridMaster - 主表grid对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  splitter - splitter控件
	 * @param  editModeDisabledIds - 【可选】编辑模式下禁用的控件ID列表
	 */
	rs.editMasterDetail = function(gridMaster, formDetail, gridDetail, splitter, editModeDisabledIds) {
		try {

			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			splitter = splitter || window.splitter || rs.get('splitter');
			editModeDisabledIds = editModeDisabledIds || window.editModeDisabledIds || [];

			var record = gridMaster.getSelected();
			if (!record) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}

			// 处理数据
			var dataForm = jQuery.extend(true, {}, formDetail.getData());
			window.opttype = Constants.OPT_EDIT;
			window.gOldData = dataForm;

			// 处理控件
			rs.toggleSplitterPane(splitter, 1, true);
			rs.toggleSplitterPane(splitter, 2, true);
			changeViewMode(Constants.VIEWMODE_EDIT, formDetail, gridDetail, gridMaster);
			editModeDisabledIds.forEach(function(id) {
				rs.setDisable(id);
			});

		} catch (e) {
			printException('editMasterDetail', e);
		}
	};

	/**
	 * 适用于主从表模式的通用删除函数
	 * 
	 * @param  fieldSettings - 字段名设置信息
	 * @param  gridMaster - 主表表格对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  urlModify - 后台服务修改地址
	 * @param  urlQuery - 后台服务查询接口
	 * @param  bRefresh - 【可选】默认为true：保存完刷新最新数据，false：保存完不刷新最新数据
	 */
	rs.removeMasterDetail = function(fieldSettings, gridMaster, formDetail, gridDetail, urlModify, urlQuery, bRefresh, searchFormId) {
		try {
			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			urlModify = urlModify || window.urlModify;
			urlQuery = urlQuery || window.urlQuery;
			bRefresh = (bRefresh !== undefined) ? bRefresh : true;

			var record = gridMaster.getSelected();
			if (!record) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}

			rs.confirm('您确认删除选中的数据吗?', '提示', function(action) {
				if (action === 'ok') {
					// 数据处理
					var item = jQuery.extend(true, {}, record);
					prehandleMiniItem(gridMaster.type, item);
					var param = jQuery.extend(true, {}, item);
					param.oldData = item;
					var removed = gridDetail.getData();
					if (removed.length > 0) {
						removed = deepCopyArray(removed);
						prehandleMiniItem(gridDetail.type, removed);
						setMxId(removed, fieldSettings.idFieldGrid, formDetail.getData(), fieldSettings.idFieldForm);
						param.oldData[fieldSettings.dataFieldDetail] = removed;
					}

					param.opttype = Constants.OPT_DEL;
					param.mkid = mkid;
					rs.postJson({
						url: urlModify,
						data: param,
						success: function(ret) {
							if (ret.ret_code.startsWith('0000')) {
								rs.showTipsSuccess('删除成功');
								changeViewMode(Constants.VIEWMODE_DELETE, formDetail, gridDetail, gridMaster);

								if (bRefresh) {
									rs.onQueryMaster(urlQuery, gridMaster, searchFormId, false);
								}
							} else {
								rs.showMessageBoxError('删除失败，' + (ret.ret_desc || '请检查重试'));
							}
						},
						error: function() {
							rs.showMessageBoxError('删除失败，请检查重试');
						}
					});
				}
			});
		} catch (e) {
			printException('removeMasterDetail', e);
		}
	};

	/**
	 * 适用于主从表模式的通用复制函数
	 * 
	 * @param  gridMaster - 主表grid对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  splitter - splitter控件
	 * @param  copyModeAutoIds - 【可选】复制模式下自动生成的控件ID列表
	 */
	rs.copyMasterDetail = function(gridMaster, formDetail, gridDetail, splitter, copyModeAutoIds) {
		try {
			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			splitter = splitter || window.splitter || rs.get('splitter');
			copyModeAutoIds = copyModeAutoIds || window.copyModeAutoIds || [];

			var item = gridMaster.getSelected();
			if (!item) {
				rs.alert('请先选择一条数据,再执行此操作！');
				return;
			}

			rs.toggleSplitterPane(splitter, 1, false);
			rs.toggleSplitterPane(splitter, 2, true);

			opttype = Constants.OPT_INSERT;

			// 处理控件
			changeViewMode(Constants.VIEWMODE_COPY, formDetail, gridDetail, gridMaster);
			copyModeAutoIds.forEach(function(id) {
				var o = rs.get(id);
				if (o && o.clear) {
					o.clear();
				}
			});
		} catch (e) {
			printException('addMasterDetail', e);
		}
	};

	/**
	 * 适用于主从表模式的通用保存函数
	 * 
	 * @param  fieldSettings - 字段名设置信息
	 * @param  gridMaster - 主表表格对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  splitter - splitter控件
	 * @param  urlModify - 后台服务修改地址
	 * @param  urlQuery - 后台服务查询接口
	 * @param  bRefresh - true：保存完刷新最新数据，false：保存完不刷新最新数据
	 */
	rs.saveMasterDetail = function(fieldSettings, gridMaster, formDetail, gridDetail, splitter, urlModify, urlQuery, bRefresh, searchFormId) {
		// 支持函数签名：rs.saveMasterDetail(settings)
		var postSuccess, postError, error;
		var deferred = jQuery.Deferred();
		if (typeof fieldSettings === 'object' && fieldSettings.fieldSettings) {
			var settings = fieldSettings;
			fieldSettings = settings.fieldSettings;
			gridMaster = settings.gridMaster;
			formDetail = settings.formDetail;
			gridDetail = settings.gridDetail;
			splitter = settings.splitter;
			urlModify = settings.urlModify;
			urlQuery = settings.urlQuery;
			postSuccess = settings.postSuccess;
			postError = settings.postError;
			error = settings.error;
			bRefresh = settings.bRefresh;
			searchFormId = settings.searchFormId;
		}

		try {
			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			splitter = splitter || window.splitter || rs.get('splitter');
			urlModify = urlModify || window.urlModify;
			urlQuery = urlQuery || window.urlQuery;
			bRefresh = (bRefresh !== undefined) ? bRefresh : false;

			gridDetail.commitEdit();
			if (!rs.formValidation(formDetail)) {
				deferred.reject(false);
				return deferred.promise();
			}
			if (!rs.gridValidation(gridDetail)) {
				deferred.reject(false);
				return deferred.promise();
			}

			var dataForm = formDetail.getData();
			var param = {};
			if (opttype === Constants.OPT_INSERT) {
				// 新增保存操作只需发送新数据给后台
				var dataGrid = gridDetail.getData();
				if (dataGrid.length > 0) {
					dataGrid = deepCopyArray(dataGrid);
					prehandleMiniItem(gridDetail.type, dataGrid);
					dataGrid.forEach(function(row) {
						row[fieldSettings.idFieldGrid] = dataForm[fieldSettings.idFieldForm];
					});
					dataForm[fieldSettings.dataFieldDetail] = dataGrid;
				}
				param.newData = dataForm;
			} else if (opttype === Constants.OPT_EDIT) {
				// 修改保存操作发送原数据、新数据及修改数据给后台
				var newData = dataForm;
				param.oldData = minus(window.gOldData, newData);
				delete param.oldData[fieldSettings.dataFieldDetail];
				var removed = gridDetail.getChanges('removed');
				if (removed.length > 0) {
					removed = deepCopyArray(removed);
					prehandleMiniItem(gridDetail.type, removed);
					setMxId(removed, fieldSettings.idFieldGrid, dataForm, fieldSettings.idFieldForm);
					param.oldData[fieldSettings.dataFieldDetail] = removed;
				}
				param.newData = newData;
				delete param.newData[fieldSettings.dataFieldDetail];
				var added = gridDetail.getChanges('added');
				if (added.length > 0) {
					added = deepCopyArray(added);
					prehandleMiniItem(gridDetail.type, added);
					setMxId(added, fieldSettings.idFieldGrid, dataForm, fieldSettings.idFieldForm);
					param.newData[fieldSettings.dataFieldDetail] = added;
				}
				param.modifyData = compareData(window.gOldData, newData);
				delete param.modifyData[fieldSettings.dataFieldDetail];
				var modified = gridDetail.getChanges('modified');
				if (modified.length > 0) {
					modified = deepCopyArray(modified);
					prehandleMiniItem(gridDetail.type, modified);
					setMxId(modified, fieldSettings.idFieldGrid, dataForm, fieldSettings.idFieldForm);
					param.modifyData[fieldSettings.dataFieldDetail] = modified;
				}
				if (!isDataModified(param)) {
					rs.showTipsSuccess('数据未修改');
					changeViewMode(Constants.VIEWMODE_SAVE, formDetail, gridDetail, gridMaster);
					deferred.resolve(true);
					return deferred.promise();
				}
			}
			param.mkid = mkid;
			param.opttype = opttype;
			rs.postJson({
				url: urlModify,
				data: param,
				success: function(ret, textStatus, jqXHR) {
					if (ret.ret_code.startsWith('0000')) {
						if (ret.ret_code === '0000') {
							rs.showTipsSuccess('保存成功');
						} else {
							rs.showTipsSuccess(ret.ret_desc);
						}
						gridDetail.accept();
						if (bRefresh) {
							rs.queryMasterDetail(urlQuery, gridMaster, formDetail, gridDetail, splitter, searchFormId, false, false);
						} else {
							if (window.gViewMode === Constants.VIEWMODE_INSERT || window.gViewMode === Constants.VIEWMODE_COPY || bRefresh) {
								rs.queryMasterDetail(urlQuery, gridMaster, formDetail, gridDetail, splitter, searchFormId, false, true);
							} else {
								rs.updateGridFromForm(gridMaster, formDetail);
								changeViewMode(Constants.VIEWMODE_SAVE, formDetail, gridDetail, gridMaster);
							}
						}
						window.gOldData = null;
						deferred.resolve(true);
					} else {
						if (typeof error === 'function') {
							error(ret, textStatus, jqXHR);
						} else {
							rs.showMessageBoxError('保存失败，' + (ret.ret_desc || '请检查重试'));
						}
						deferred.reject(false);
					}

					if (typeof postSuccess === 'function') {
						postSuccess(ret, textStatus, jqXHR);
					}
				},
				error: function(jqXHR, textStatus, errorThrown) {
					rs.showMessageBoxError('保存失败，请检查重试');
					deferred.reject(false);
					if (typeof postError === 'function') {
						postError(jqXHR, textStatus, errorThrown);
					}
				}
			});
		} catch (e) {
			printException('saveMasterDetail', e);
			deferred.reject(false);
		}
		return deferred.promise();
	};

	/**
	 * 适用于主从表模式的通用取消函数
	 * 
	 * @param  gridMaster - 主表表格对象
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  splitter - splitter控件
	 * @param  urlQuery - 后台服务查询接口
	 * @param  dataFieldDetail - 后台主表对象中关联子表对象集合的字段名
	 */
	rs.cancelMasterDetail = function(gridMaster, formDetail, gridDetail, splitter, urlQuery, dataFieldDetail) {
		var deferred = jQuery.Deferred();
		try {
			gridMaster = gridMaster || window.gridMaster || rs.get('gridMaster');
			formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
			gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
			urlQuery = urlQuery || window.urlQuery;
			dataFieldDetail = dataFieldDetail || window.dataFieldDetail;

			// validation
			if (!isDatagrid(gridMaster) || !isDatagrid(gridDetail)) {
				printErrorIllegal('cancelMasterDetail');
				deferred.reject(false);
				return deferred.promise();
			}

			rs.confirm('您确认放弃保存正在编辑的数据吗?', '提示', function(action) {
				if (action === 'ok') {
					if (window.gViewMode === Constants.VIEWMODE_INSERT || window.gViewMode === Constants.VIEWMODE_COPY) {
						rs.queryMasterDetail(urlQuery, gridMaster, formDetail, gridDetail, splitter);
					} else {
						rs.selectionChangedMaster({
							sender: gridMaster
						}, urlQuery, formDetail, gridDetail, dataFieldDetail);
					}
					deferred.resolve(true);
				} else {
					deferred.reject(false);
				}
			});
		} catch (e) {
			printException('cancelMasterDetail', e);
			deferred.reject(false);
		}
		return deferred.promise();
	};

	/**
	 * 主从表模式中主表记录切换
	 * 
	 * @param  e - 事件对象
	 * @param  urlQuery - 后台服务查询接口
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  dataFieldDetail - 后台主表对象中关联子表对象集合的字段名
	 * 
	 */
	rs.selectionChangedMaster = function(e, urlQuery, formDetail, gridDetail, dataFieldDetail) {
		urlQuery = urlQuery || window.urlQuery;
		formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
		gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
		dataFieldDetail = dataFieldDetail || window.dataFieldDetail;

		var gridMaster = e.sender;
		var record = gridMaster.getSelected();
		if (record) {
			try {
				var item = jQuery.extend(true, {}, record);
				delete item[dataFieldDetail];
				prehandleMiniItem(gridMaster.type, item);

				var param = item;
				param.mkid = mkid;
				param.opttype = Constants.OPT_QUERY;

				formDetail.reset();
				if (dataFieldDetail) {
					gridDetail.clearRows();
				}
				jQuery.ajax({
					url: urlQuery,
					type: 'post',
					data: param,
					success: function(ret) {
						if (ret.ret_code.startsWith('0000')) {
							var data = ret.data;
							if (data && data.length > 0) {
								formDetail.setData(data[0]);
								if (data[0][dataFieldDetail]) {
									gridDetail.setData(data[0][dataFieldDetail]);
								}
							}
						} else {
							rs.showMessageBoxError('加载失败，' + (ret.ret_desc || '请检查重试'));
						}
					},
					error: function() {
						rs.showMessageBoxError('加载失败，请检查重试');
					}
				});

				// 处理控件
				changeViewMode(Constants.VIEWMODE_QUERY, formDetail, gridDetail, gridMaster);
			} catch (e) {
				printException('selectionChangedMaster', e);
			}
		}
	};

	/**
	 * 主从表模式中通过行点击主表来切换从表显示记录
	 * 
	 * @param  e - 事件对象
	 * @param  urlQuery - 后台服务查询接口
	 * @param  formDetail - 从表表单对象
	 * @param  gridDetail - 从表表格对象
	 * @param  dataFieldDetail - 后台主表对象中关联子表对象集合的字段名
	 * 
	 */
	rs.onRowClickMaster = function(e, urlQuery, formDetail, gridDetail, dataFieldDetail) {
		urlQuery = urlQuery || window.urlQuery;
		formDetail = formDetail || window.formDetail || rs.newForm('formDetail');
		gridDetail = gridDetail || window.gridDetail || rs.get('gridDetail');
		dataFieldDetail = dataFieldDetail || window.dataFieldDetail;

		var gridMaster = e.sender;
		var record = e.record;
		if (record) {
			try {
				var item = jQuery.extend(true, {}, record);
				delete item[dataFieldDetail];
				prehandleMiniItem(gridMaster.type, item);

				var param = item;
				param.mkid = mkid;
				param.opttype = Constants.OPT_QUERY;

				formDetail.reset();
				if (dataFieldDetail) {
					gridDetail.clearRows();
				}
				jQuery.ajax({
					url: urlQuery,
					type: 'post',
					data: param,
					success: function(ret) {
						if (ret.ret_code.startsWith('0000')) {
							var data = ret.data;
							if (data && data.length > 0) {
								formDetail.setData(data[0]);
								if (data[0][dataFieldDetail]) {
									gridDetail.setData(data[0][dataFieldDetail]);
								}
							}
						} else {
							rs.showMessageBoxError('加载失败，' + (ret.ret_desc || '请检查重试'));
						}
					},
					error: function() {
						rs.showMessageBoxError('加载失败，请检查重试');
					}
				});

				// 处理控件
				changeViewMode(Constants.VIEWMODE_QUERY, formDetail, gridDetail, gridMaster);
			} catch (e) {
				printException('selectionChangedMaster', e);
			}
		}
	};

	/**
	 * 通用的表单校验函数
	 */
	rs.formValidation = function(form) {
		form.validate();
		if (!form.isValid()) {
			rs.showtips('提示', '请检查输入项是否有效！', 'info');
			return false;
		}
		return true;
	};

	/**
	 * 通用的表格校验函数
	 */
	rs.gridValidation = function(grid) {
		grid.validate();
		if (grid.isValid() === false) {
			var error = grid.getCellErrors()[0];
			grid.beginEditCell(error.record, error.column);
			rs.showMessageBoxError(error.errorText);
			return false;
		}
		return true;
	};
	/*------------------------------------- 主体流程类结束 ----------------------------------*/


	/*--------------------------------------- 辅助类开始 ------------------------------------*/
	rs.newForm = function(id) {
		return new mini.Form('#' + id);
	};

	// 将Date对象转换为字符串
	// date: 日期类型对象。
	// string: 格式化字符串。例如："yyyy-MM-dd HH:mm:ss"。
	rs.formatDate = function(date, string) {
		return mini.formatDate(date, string);
	};

	// 将字符串解析为Date对象
	rs.parseDate = function(strDate) { // 二次封装日期字符转换为js日期类型函数
		return mini.parseDate(strDate);
	};

	// 弹出窗口
	rs.showWindow = function(win, width, height, title, form, option) {
		return showWindow(win, width, height, title, form, option);
	};

	// 强制把输入的小写字母转换成大写
	rs.forceUpperCase = function(e) {
		var item = e.sender;
		var value="";
		if ("buttonedit" === e.sender.type)
			value = item.getValue();
		else if ("textbox" === e.sender.type)
			value = item.getInputText();
		var newValue = value.toUpperCase();
		item.setValue(newValue);
		if (item.setText) {
			item.setText(newValue);
		}
	};

	// 强制把输入的小写字母转换成大写
	rs.forceLowerCase = function(e) {
		var item = e.sender;
		var value="";
		if ("buttonedit" === e.sender.type)
			value = item.getValue();
		else if ("textbox" === e.sender.type)
			value = item.getInputText();
		var newValue = value.toLowerCase();
		item.setValue(newValue);
		if (item.setText) {
			item.setText(newValue);
		}
	};

	// 禁用控件
	rs.setDisable = function(id) {
		if (mini.get(id)) {
			mini.get(id).disable();
		}
	};

	// 启用控件
	rs.setEnable = function(id) {
		if (mini.get(id)) {
			mini.get(id).enable();
		}
	};

	// 日期的显示转换函数
	rs.onDateRenderer = function(e) {
		var value = e.value;
		if (value) return rs.formatDate(value, 'yyyy-MM-dd');
		return '';
	};

	// 布尔值的显示转换函数
	rs.onBooleanRenderer = function(e) {
		if (e.value === 'Y') {
			return '是';
		}
		return '否';
	};
		
	// 启动/停止的显示转换函数
	rs.onStartStopRenderer = function(e) {
		if (e.value === 'Y') {
			return '启动';
		}
		return '停止';
	};

	// 是否已婚的显示转换函数
	rs.onMarriedRenderer = function(e) {
		if (e.value === 1) return '是';
		else return '否';
	};
	
	// 性别的显示转换函数
	rs.onGenderRenderer = function(e) {
		var Genders = [{
			id: 1,
			text: '男'
		}, {
			id: 2,
			text: '女'
		}];
		for (var i = 0, l = Genders.length; i < l; i++) {
			var g = Genders[i];
			if (g.id === e.value) return g.text;
		}
		return '';
	};

	// 控制splitter控件的面板展开/收缩
	rs.toggleSplitterPane = function(splitter, indexPane, expand) {
		if (expand === true) {
			splitter.expandPane(indexPane);
		} else {
			splitter.collapsePane(indexPane);
		}
	};

	// 控制主从表中splitter控件的面板自动展开/收缩
	rs.toggleSplitterMasterDetail = function(splitter) {
		var p2 = splitter.getPane(2);
		if (p2) {
			if (p2.expanded) {
				splitter.collapsePane(2);
			} else {
				splitter.expandPane(2);
			}
		}
	};

	// Grid末尾添加新行
	rs.addGridRow = function(grid, rowidField, xuhaoField, obj) {
		grid.commitEdit();
		var newRow = obj || {};
		if (rowidField) {
			newRow[rowidField] = getNextRowid(grid.getData(), rowidField);
		}
		if (xuhaoField) {
			newRow[xuhaoField] = getNextXuhao(grid.getData(), xuhaoField);
		}
		grid.addRow(newRow);
		grid.allowCellEdit = true;
		if (newRow[xuhaoField]) {
			grid.setCurrentCell([newRow, grid.getColumn(1)]);
		} else {
			grid.setCurrentCell([newRow, grid.getColumn(0)]);
		}
		grid.beginEditCell();
	};

	// Grid删除当前选中行
	rs.removeGridRow = function(grid, xuhaoField) {
		var row = grid.getSelected();
		if (!row) {
			rs.alert('请先选择一行数据,再执行此操作！');
			return;
		}

		grid.removeRow(grid.getSelected(), true);
	};

	// Grid复制当前选中行
	rs.cloneGridRow = function(grid, rowidField, xuhaoField) {
		var row = grid.getSelected();
		if (!row) {
			rs.alert('请先选择一行数据,再执行此操作！');
			return;
		}

		var newRow = jQuery.extend(true, {}, row);
		newRow[xuhaoField] = getNextXuhao(grid.getData(), xuhaoField);
		newRow[rowidField] = getNextRowid(grid.getData(), rowidField);
		grid.addRow(newRow);
		grid.allowCellEdit = true;
		if (newRow[xuhaoField]) {
			grid.setCurrentCell([newRow, grid.getColumn(1)]);
		} else {
			grid.setCurrentCell([newRow, grid.getColumn(0)]);
		}
		grid.beginEditCell();
	};

	// Grid上移当前选中行
	rs.moveUpGridRow = function(grid, xuhaoField) {
		var row = grid.getSelected();
		if (!row) {
			rs.alert('请先选择一行数据,再执行此操作！');
			return;
		}

		var index = grid.indexOf(row);
		grid.moveRow(row, index - 1);

		if (xuhaoField) {
			var obj = {};
			obj[xuhaoField] = index + 1;
			grid.updateRow(grid.getRow(index), obj);
			obj[xuhaoField] = index;
			grid.updateRow(grid.getRow(index - 1), obj);
		}
	};

	// Grid下移当前选中行
	rs.moveDownGridRow = function(grid, xuhaoField) {
		var row = grid.getSelected();
		if (!row) {
			rs.alert('请先选择一行数据,再执行此操作！');
			return;
		}

		var index = grid.indexOf(row);
		grid.moveRow(row, index + 2);

		if (xuhaoField) {
			var obj = {};
			obj[xuhaoField] = index + 1;
			grid.updateRow(grid.getRow(index), obj);
			obj[xuhaoField] = index + 2;
			grid.updateRow(grid.getRow(index + 1), obj);
		}
	};

	// Grid重排序号列
	rs.reorderGridRow = function(grid, xuhaoField) {
		var data = grid.data;
		if (data && xuhaoField) {
			for (var i = 0; i < data.length; i++) {
				var obj = {};
				obj[xuhaoField] = i + 1;
				grid.updateRow(grid.getRow(i), obj);
			}
		}
	};

	// 判断浮点数近似相等
	rs.equalsFloat = function(f1, f2, epsilon) {
		epsilon = epsilon || 0.00000001;
		if (f1 === f2) {
			return true;
		}

		var diff = Math.abs(f1 - f2);
		return diff < epsilon;
	};

	// Form的数据更新到Grid当前选中行
	rs.updateGridFromForm = function(grid, form) {
		grid.updateRow(grid.getSelected(), compareData(grid.getSelected(), form.getData()));
	};

	// 按钮输入框点击关闭按钮
	rs.onCloseClick = function(e) {
		var obj = e.sender;
		obj.setText('');
		obj.setValue('');
	};

	// 预处理miniui控件数据，删除内部字段
	rs.prehandleMiniItem = function(type, item) {
		prehandleMiniItem(type, item);
	};

	rs.changeViewMode = function(viewMode, formDetail, gridDetail, gridMaster) {
		changeViewMode(viewMode, formDetail, gridDetail, gridMaster);
	};

	rs.deepCopyArray = function(arr) {
		return deepCopyArray(arr);
	};
	/*--------------------------------------- 辅助类结束 ------------------------------------*/


	/*------------------------------------- 私有辅助函数开始 ---------------------------------*/
	var _gridToolbarControllers = ['btnAddRow', 'btnRemoveRow', 'btnCloneRow', 'btnMoveUpRow', 'btnMoveDownRow', 'btnReorderRow'];

	function compareData(oldData, newData) {
		if (typeof oldData !== 'object' || typeof newData !== 'object') {
			return null;
		}

		var result = {};
		jQuery.each(newData, function(key, value) {
			if (!compare(value, oldData[key])) {
				result[key] = value;
			}
		});
		return result;
	}

	function minus(oldData, newData) {
		if (typeof oldData !== 'object' || typeof newData !== 'object') {
			return null;
		}

		var result = {};
		jQuery.each(oldData, function(key, value) {
			if (newData.hasOwnProperty(key)) {
				result[key] = value;
			}
		});
		return result;
	}

	// 非严格非递归比较
	function compare(o1, o2) {
		if (Object.prototype.toString.apply(o1) === '[object Date]' && Object.prototype.toString.apply(o2) === '[object Date]') {
			return o1.getTime() == o2.getTime();
		}

		if ((o1 === null && o2 === '') || (o1 === '' && o2 === null)) {
			return true;
		}
		return o1 == o2;
	}

	function prehandleMiniItem(type, item) {
		if (Array.isArray(item)) {
			item.forEach(function(o) {
				prehandleMiniItem(type, o);
			});
		} else {
			if (type === 'datagrid') {
				delete item._id;
				delete item._uid;
				delete item._state;
			} else if (type === 'treegrid') {
				delete item._id;
				delete item._uid;
				delete item._pid;
				delete item._level;
				delete item.checked;
				delete item.expanded;
				delete item.children; // todo
			}
		}
	}

	function deleteAllDateField(obj) {
		jQuery.each(obj, function(key, value) {
			if (jQuery.type(value) === 'date') {
				delete obj[key];
			}
		});
	}

	function setMxId(dataGrid, idFieldGrid, dataForm, idFieldForm) {
		dataGrid.forEach(function(row) {
			row[idFieldGrid] = dataForm[idFieldForm];
		});
	}

	function getNextXuhao(dataGrid, xuhaoField) {
		var maxXuhao = 0;
		if (dataGrid) {
			dataGrid.forEach(function(row) {
				if (row[xuhaoField] && row[xuhaoField] > maxXuhao) {
					maxXuhao = row[xuhaoField];
				}
			});
		}
		return maxXuhao + 1;
	}

	function getNextRowid(dataGrid, rowidField) {
		var maxRowId = 0;
		if (dataGrid) {
			dataGrid.forEach(function(row) {
				if (row[rowidField] && row[rowidField] > maxRowId) {
					maxRowId = row[rowidField];
				}
			});
		}
		return maxRowId + 1;
	}

	/**
	 * 根据视图模式设置页面控件的状态
	 * 
	 * @param   viewMode 				视图模式
	 */
	function changeViewMode(viewMode, formDetail, gridDetail, gridMaster) {
		if (viewMode !== window.gViewMode) {
			window.gViewMode = viewMode;

			if (viewMode === Constants.VIEWMODE_QUERY) {
				rs.setEnable('btnSearch');
				rs.setEnable('btnAdd');
				rs.setEnable('btnEdit');
				rs.setEnable('btnRemove');
				rs.setEnable('btnCopy');
				rs.setDisable('btnSave');
				rs.setDisable('btnCancel');

				showSearchPanel('pnlsearch');
				setTimeout(function() {
					rs.layout();
				}, 1);

				if (gridMaster) {
					gridMaster.allowRowSelect = true;
				}
				if (formDetail) {
					formDetail.setEnabled(false);
				}
				if (gridDetail) {
					gridDetail.allowCellEdit = false;
				}
			} else if (viewMode === Constants.VIEWMODE_INSERT) {
				rs.setDisable('btnSearch');
				rs.setDisable('btnAdd');
				rs.setDisable('btnEdit');
				rs.setDisable('btnRemove');
				rs.setDisable('btnCopy');
				rs.setEnable('btnSave');
				rs.setEnable('btnCancel');

				hideSearchPanel('pnlsearch');
				setTimeout(function() {
					rs.layout();
				}, 1);

				if (gridMaster) {
					gridMaster.clearSelect(false);
					gridMaster.allowRowSelect = false;
				}
				if (formDetail) {
					formDetail.reset();
					formDetail.setEnabled(true);
				}
				if (gridDetail) {
					gridDetail.clearRows();
					gridDetail.allowCellEdit = true;
				}
			} else if (viewMode === Constants.VIEWMODE_EDIT) {
				rs.setDisable('btnSearch');
				rs.setDisable('btnAdd');
				rs.setDisable('btnEdit');
				rs.setDisable('btnRemove');
				rs.setDisable('btnCopy');
				rs.setEnable('btnSave');
				rs.setEnable('btnCancel');

				hideSearchPanel('pnlsearch');
				setTimeout(function() {
					rs.layout();
				}, 1);

				if (gridMaster) {
					gridMaster.allowRowSelect = false;;
				}
				if (formDetail) {
					formDetail.setEnabled(true);
				}
				if (gridDetail) {
					gridDetail.allowCellEdit = true;
				}
			} else if (viewMode === Constants.VIEWMODE_DELETE) {
				rs.setEnable('btnSearch');
				rs.setEnable('btnAdd');
				rs.setEnable('btnEdit');
				rs.setEnable('btnRemove');
				rs.setEnable('btnCopy');
				rs.setDisable('btnSave');
				rs.setDisable('btnCancel');

				showSearchPanel('pnlsearch');
				setTimeout(function() {
					rs.layout();
				}, 1);

				if (gridMaster) {
					gridMaster.allowRowSelect = true;
				}
				if (formDetail) {
					formDetail.reset();
				}
				if (gridDetail) {
					gridDetail.clearRows();
				}
			} else if (viewMode === Constants.VIEWMODE_COPY) {
				rs.setDisable('btnSearch');
				rs.setDisable('btnAdd');
				rs.setDisable('btnEdit');
				rs.setDisable('btnRemove');
				rs.setDisable('btnCopy');
				rs.setEnable('btnSave');
				rs.setEnable('btnCancel');

				hideSearchPanel('pnlsearch');
				setTimeout(function() {
					rs.layout();
				}, 1);

				if (gridMaster) {
					gridMaster.clearSelect(false);
					gridMaster.allowRowSelect = false;
				}
				if (formDetail) {
					formDetail.setEnabled(true);
				}
				if (gridDetail) {
					gridDetail.allowCellEdit = true;
				}
			} else if (viewMode === Constants.VIEWMODE_SAVE) {
				rs.setEnable('btnSearch');
				rs.setEnable('btnAdd');
				rs.setEnable('btnEdit');
				rs.setEnable('btnRemove');
				rs.setEnable('btnCopy');
				rs.setDisable('btnSave');
				rs.setDisable('btnCancel');

				showSearchPanel('pnlsearch');
				setTimeout(function() {
					rs.layout();
				}, 1);

				if (gridMaster) {
					gridMaster.allowRowSelect = true;
				}
				if (formDetail) {
					formDetail.setEnabled(false);
				}
				if (gridDetail) {
					gridDetail.allowCellEdit = false;
				}
			}

			changeControllerMode(viewMode, _gridToolbarControllers);
		}
	}

	/**
	 * 根据视图模式设置Grid工具栏控件的只读
	 * 
	 * @param   viewMode 				视图模式
	 * @param   controllers 		控件ID数组
	 */
	function changeControllerMode(viewMode, controllers) {
		if (!Array.isArray(controllers)) {
			return;
		}

		if (viewMode === Constants.VIEWMODE_INSERT || viewMode === Constants.VIEWMODE_COPY || viewMode === Constants.VIEWMODE_EDIT) {
			controllers.forEach(function(id) {
				rs.setEnable(id);
			});
		} else {
			controllers.forEach(function(id) {
				rs.setDisable(id);
			});
		}
	}

	function isDataModified(param) {
		if (!jQuery.isEmptyObject(param.modifyData)) {
			return true;
		}

		if ((param.oldData && param.oldData.mxs && param.oldData.mxs.length > 0) ||
			(param.newData && param.newData.mxs && param.newData.mxs.length > 0) ||
			(param.modifyData && param.modifyData.mxs && param.modifyData.mxs.length > 0)) {
			return true;
		}

		return false;
	}

	function isDatagrid(obj) {
		return (obj && obj.type === 'datagrid');
	}

	function isSplitter(obj) {
		return (obj && obj.type === 'splitter');
	}

	function printErrorIllegal(funcName) {
		console.error(funcName + '函数传入参数类型不匹配');
	}

	function printException(e, funcName) {
		console.error(funcName + '函数执行时发生异常: ' + e);
	}

	function findInArray(arr, key, keyField) {
		for (var i = 0; i < arr.length; i++) {
			if (arr[i][keyField] === key) {
				return true;
			}
		}
		return false;
	}

	function deepCopyArray(arr) {
		var result = [];
		for (var i = 0; i < arr.length; i++) {
			result.push(jQuery.extend(true, {}, arr[i]));
		}
		return result;
	}

	function hideSearchPanel(id) {
		var panel = rs.get(id);
		if (panel) {
			panel.setExpanded(false);
		}
	}

	function showSearchPanel(id) {
		var panel = rs.get(id);
		if (panel) {
			panel.setExpanded(true);
		}
	}
	
	/**
	 * 设置物料属性列显示
	 * 
	 * @param   masterGrid 			设置列表
	 */
	rs.ResetWLSXColumn = function(masterGrid, hide){
		var thcolumn = masterGrid.getColumn("th");
		var czcolumn = masterGrid.getColumn("cz");
		if (hide) {
			masterGrid.updateColumn(thcolumn, {
				visible : false
			});
			masterGrid.updateColumn(czcolumn, {
				visible : false
			});
		} else {
			masterGrid.updateColumn(thcolumn, {
				visible : true
			});
			masterGrid.updateColumn(czcolumn, {
				visible : true
			});
		}
   		var urlGetWLSXSZ = './jcsj/getWLSXSZ.do'; 
     	       rs.ajax({
     	         url: urlGetWLSXSZ
     	         }).done(function(data){
     	        	if(data)
     	         	{		
     	         		var columnsAll = masterGrid.getColumns();
     	         		for (var i = 0; i < data.length; i++) {
     	         				var zdfield = data[i].zdid.substring(data[i].zdid.indexOf('_') + 1,data[i].zdid.length);
     	         				var column = masterGrid.getColumn(zdfield);
     	         				if (columnsAll.indexOf(column) > -1)
     	         				{
	     	         				columnsAll.splice(columnsAll.indexOf(column),1);
	     	         				var zdlx = data[i].zdlx;
									masterGrid.updateColumn(column,{ header: data[i].zdmc});	
									masterGrid.updateColumn(column,{ width: data[i].xskd});
									if (zdlx == "F")	
									{
										masterGrid.updateColumn(column,{ numberFormat: "n" + data[i].xsws.toString()});
									}
									masterGrid.updateColumn(column,{ visible: true});
									columnsAll.push(column);
								}	
							}
						masterGrid.setColumns(columnsAll);
     	         	}       	 
     	       });							
   	}  
	
	/**
	 * 设置物料属性列显示
	 * 
	 * @param   masterGrid 			设置列表
	 */
	rs.ResetMTXXColumn = function(masterGrid){
   		var urlGetMTXXSZ = './xs/getmtxxsz.do'; 
     	       rs.ajax({
     	         url: urlGetMTXXSZ
     	         }).done(function(data){
     	        	if(data)
     	         	{		
     	         		var columnsAll = masterGrid.getColumns();
     	         		for (var i = 0; i < data.length; i++) {
     	         				var zdfield = data[i].zdid.substring(data[i].zdid.indexOf('_') + 1,data[i].zdid.length);
     	         				var column = masterGrid.getColumn(zdfield);
     	         				if (columnsAll.indexOf(column) > -1)
     	         				{
	     	         				columnsAll.splice(columnsAll.indexOf(column),1);
									masterGrid.updateColumn(column,{ header: data[i].zdmc});	
									masterGrid.updateColumn(column,{ width: data[i].xskd});					
									masterGrid.updateColumn(column,{ visible: true});
									columnsAll.push(column);
								}	
							}
						masterGrid.setColumns(columnsAll);
     	         	}       	 
     	       });							
   	}  
	
	/**
	 * 设置物料批号列隐藏
	 * 
	 * @param   masterGrid 			设置列表
	 */
	rs.HideWLPHColumn = function(masterGrid, hide){				
		var urlGetWLPHSZ = './jcsj/getWLPHSZ.do';
	       rs.ajax({
	         url: urlGetWLPHSZ
	         }).done(function(data){       
	         	if(data)
	         	{	
			 		var columnsAll = masterGrid.getColumns();
			 		for (var i = 0; i < data.length; i++) {
			 			var zdfield = data[i].sxzd.substring(data[i].sxzd.indexOf('_') + 1,data[i].sxzd.length);
         				var column = masterGrid.getColumn(zdfield);
						if (hide){
			 				masterGrid.updateColumn(column,{ visible: false});
			 			}else
			 			{
			 				masterGrid.updateColumn(column,{ visible: true});		
			 			}
					}
	         	}
	         });
	}  
	
	/**
	 * 设置物料属性列隐藏
	 * 
	 * @param   masterGrid 			设置列表
	 * @param 	hide				是否隐藏
	 */
	rs.HideWLSXColumn = function(masterGrid,hide){
   		var urlGetWLPHSZ = './jcsj/getWLSXSZ.do';
	       rs.ajax({
	         url: urlGetWLPHSZ
	         }).done(function(data){       
	         	if(data)
	         	{	
			 		var columnsAll = masterGrid.getColumns();
			 		for (var i = 0; i < data.length; i++) {
			 			var zdfield = data[i].zdid.substring(data[i].zdid.indexOf('_') + 1,data[i].zdid.length);
	         			var column = masterGrid.getColumn(zdfield);
						if (hide){
			 				masterGrid.updateColumn(column,{ visible: false});
			 			}else
			 			{
			 				masterGrid.updateColumn(column,{ visible: true});		
			 			}
					}
	         	}
	         });
	}  
	
	/**
	 * 设置批号属性列显示
	 * 
	 * @param   masterGrid 			设置列表
	 */
	rs.ShowWLPHColumn = function(masterGrid){
   		var urlGetWLPHSZ = './jcsj/getWLPHSZ.do';
     	       rs.ajax({
     	         url: urlGetWLPHSZ
     	         }).done(function(data){       
     	         	if(data)
     	         	{		
     	         		var columnsAll = masterGrid.getColumns();
     	         		for (var i = 0; i < data.length; i++) {
     	         				var zdfield = data[i].sxzd.substring(data[i].sxzd.indexOf('_') + 1,data[i].sxzd.length);
     	         				var column = masterGrid.getColumn(zdfield);
     	         				if (columnsAll.indexOf(column) > -1)
     	         				{        					
	     	         				columnsAll.splice(columnsAll.indexOf(column),1);
	     	         				var zdlx = data[i].zlx;
	     	         				var MJ = data[i].sfmj;
									masterGrid.updateColumn(column,{ header: data[i].sxmc});	
									masterGrid.updateColumn(column,{ width: data[i].width});
									masterGrid.updateColumn(column,{ maxLength: data[i].len});
									column.readOnly = true;
									if (MJ == "Y")
									{	
										column.editor.cls = "mini-combobox";
										column.editor.type = "combobox";
										column.editor.allowInput="false"
										var MJZ = data[i].mjzy;
										var MJValue = MJZ.split("\n");	
										var comboxData = [];
										
										var valueData = {
												"id": "",
												"text": ""
										};
										comboxData.push(valueData);
										for (var j = 0; j < MJValue.length; j++) {
											if (zdlx == "N"){		
												var value = parseFloat(MJValue[j]);
											}
											else if (zdlx == "D"){
												var date = new Date(MJValue[j]);
												var value = date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
											}
											else{
												var value = MJValue[j];
											}
											var valueData = {
													"id": value,
													"text": value
											};
											comboxData.push(valueData);												
										}	
										column.editor.data = comboxData;
									}
									masterGrid.updateColumn(column,{ visible: true});
									columnsAll.push(column);
								}	
							}
						masterGrid.setColumns(columnsAll);
     	         	} 
     	       });							
   	}  
	
	/**
	 * 设置批号属性列显示
	 * 
	 * @param   masterGrid 			设置列表
	 */
	
	rs.ResetWLPHColumn = function(masterGrid){		
		 var urlGetWLPHSZ = './jcsj/getWLPHSZ.do';
         rs.ajax({
         url: urlGetWLPHSZ
         }).done(function(data){       
         	if(data)
         	{		
         		var columnsAll = masterGrid.getColumns();
         		for (var i = 0; i < data.length; i++) {
         				var zdfield = data[i].sxzd.substring(data[i].sxzd.indexOf('_') + 1,data[i].sxzd.length);
         				var column = masterGrid.getColumn(zdfield);
         				if (columnsAll.indexOf(column) > -1)
         				{        					
     	         				columnsAll.splice(columnsAll.indexOf(column),1);
     	         				var zdlx = data[i].zlx;
     	         				var MJ = data[i].sfmj;
								masterGrid.updateColumn(column,{ header: data[i].sxmc});	
								masterGrid.updateColumn(column,{ width: data[i].width});
								masterGrid.updateColumn(column,{ maxLength: data[i].len});
								if (MJ == "Y")
								{	
									column.editor.cls = "mini-combobox";
									column.editor.type = "combobox";
									column.editor.allowInput="false"
									var MJZ = data[i].mjzy;
									var MJValue = MJZ.split("\n");	
									var comboxData = [];
									
									var valueData = {
											"id": "",
											"text": ""
									};
									comboxData.push(valueData);
									for (var j = 0; j < MJValue.length; j++) {
										if (zdlx == "N"){		
											var value = parseFloat(MJValue[j]);
										}
										else if (zdlx == "D"){
											var date = new Date(MJValue[j]);
											var value = date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
										}
										else{
											var value = MJValue[j];
										}
										var valueData = {
												"id": value,
												"text": value
										};
										comboxData.push(valueData);												
									}	
									column.editor.data = comboxData;
								}
								masterGrid.updateColumn(column,{ visible: true});
								columnsAll.push(column);
							}	
						}
					masterGrid.setColumns(columnsAll);
         	} 
       });	   								
   	}  
	
	rs.getSXUrl = function(wlid){
		return './jcsj/' + wlid + '/getSXZSX.do';
	}
	
	rs.SetSXGridColumnState = function(wlid,deferred1){
		var urlGetSXZSX = './jcsj/' + wlid + '/getSXZSX.do';
		rs.ajax({
			url: urlGetSXZSX
				}).done(function(data){       
					if(data)
					{			
						var columnsAll = masterGrid.getColumns();
						for (var i = 0; i < data.length; i++) {
							var zdfield = data[i].sxzd.substring(data[i].sxzd.indexOf('_') + 1,data[i].sxzd.length);
							var column = masterGrid.getColumn(zdfield);
							var qybz = data[i].qybz;
							if (columnsAll.indexOf(column) > -1)
							{   
								if(qybz == 'Y'){
									column.readOnly = false;	
								}
								else{
									column.readOnly = true;
								}			
							}
						}
					}
			});	
	}  
	
	rs.SetDefauleWlph = function(sender, wlid, wlph, record, masterGrid){
		if (((sender == "WLPH") && (($.trim(wlph) != '') && ($.trim(wlid) != '')))
			|| ((sender == "WLID") && ($.trim(wlid) != ''))){
			var urlgetDefauleWlph = './pub/' + encodeURIComponent(wlid) + '/' + encodeURIComponent(wlph) + '/' + encodeURIComponent(sender) + '/getDefauleWlph.do';
			rs.ajax({
				url: urlgetDefauleWlph
					}).done(function(data){       
						if(data)
						{	
							var rowData = getPhData(data);
							masterGrid.updateRow(record,rowData);
						} 
		   });	
		}
   	}  
	
	rs.SetDefauleWlsx = function(wlid, record, masterGrid){
		if ($.trim(wlid) != ''){
			var urlgetDefauleWlsx = './pub/' + encodeURIComponent(wlid) + '/getDefauleWlSX.do';
			rs.ajax({
				url: urlgetDefauleWlsx
					}).done(function(data){       
						if(data)
						{	
							var rowData = getSxData(data);
							
						}else{
							var rowData = {sxzd01:null,sxzd02:null,sxzd03:null,sxzd04:null,sxzd05:null,
										   sxzd06:null,sxzd07:null,sxzd08:null,sxzd09:null,sxzd10:null,
										   sxzd11:null,sxzd12:null,sxzd13:null,sxzd14:null,sxzd15:null};
						}
						masterGrid.updateRow(record,rowData);
							
		   });	
		}else{
			var rowData = {sxzd01:null,sxzd02:null,sxzd03:null,sxzd04:null,sxzd05:null,
					       sxzd06:null,sxzd07:null,sxzd08:null,sxzd09:null,sxzd10:null,
						   sxzd11:null,sxzd12:null,sxzd13:null,sxzd14:null,sxzd15:null};
			gridDetail.updateRow(record,rowData);
		}		
   	} 
	
	function getPhData(srcData) {
		var result = {};
		jQuery.each(srcData, function(key, value) {
			if (key.length > 2){
				var zdField = key.substring(0,2);
				if (zdField == 'ph'){
					result[key] = value;
				}
			}
				 
		});
		return result;
	}
	
	function getSxData(srcData) {
		var result = {};
		jQuery.each(srcData, function(key, value) {
			if (key.length > 2){
				var zdField = key.substring(0,2);
				if (zdField == 'sx'){
					result[key] = value;
				}
			}
				 
		});
		return result;
	}
	
	/*------------------------------------- 私有辅助函数结束 ---------------------------------*/
	return rs;
})(window.rs || {});